#ifndef UTILITIES_H
#define UTILITIES_H

#include "common.h"

#ifdef UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif

#ifdef _WIN64
#define GCL_HBRBACKGROUND GCLP_HBRBACKGROUND
#define	GCL_HCURSOR GCLP_HCURSOR
#define	GCL_HICON GCLP_HICON
#define	GWL_HINSTANCE GWLP_HINSTANCE
#endif

#define RECTWIDTH(r)	((LONG)(r.right - r.left))
#define RECTHEIGHT(r)	((LONG)(r.bottom - r.top))
#define WPRIGHT(wp)		((LONG)(wp.x + wp.cx))
#define WPBOTTOM(wp)	((LONG)(wp.y + wp.cy))

#define PRECTWIDTH(r)	((LONG)(r->right - r->left))
#define PRECTHEIGHT(r)	((LONG)(r->bottom - r->top))
#define PWPRIGHT(wp)	((LONG)(wp->x + wp->cx))	
#define PWPBOTTOM(wp)	((LONG)(wp->y + wp->cy))		

class DLL TStringSortTemplate
{
public:
	inline bool operator()(tstring ts1, tstring ts2) const
	{
		return _tcsicmp(ts1.c_str(),ts2.c_str()) < 0;
	}
};

struct DLL Grid
{
	int Columns;
	int Rows;
};

class DLL Utilities
{
public:
	enum DesktopWindow
	{
		DW_ProgMan,
		DW_SHELLDLL_DefViewParent,
		DW_SHELLDLL_DefView,
		DW_SysListView32
	};	
	enum FileType
	{
		FT_FILE=0x01,
		FT_DIRECTORY=0x02
	};	

	static HWND GetDesktopWindow(DesktopWindow desktopWindow);
	static bool IsValidTaskWindow(HWND hWnd, bool allowMinimized=true, bool allowMaximized=true);
	static bool IsSpecialWindow(HWND hWnd);
	static POINT GetCursorPosition();
	static HWND TopLevelWindow(HWND hWnd);
	static HWND TopLevelWindowFromMousePosition();
	static bool RectContainsPoint(RECT r, POINT p);
	static bool IsTopMost(HWND hWnd);
	static void SetTopMost(HWND hWnd);
	static void SetNoTopMost(HWND hWnd);
	static void ShowHWNDInfo(HWND hWnd);
	static BOOL KillProcess(DWORD pID);
	static RECT CalcWindowRect(HWND hWnd);
	static HWND GetWindowFromPointEx(POINT point);
	static void GetWindowTextEx(HWND hWnd, TCHAR* lpText);
	static void DrawDwmCompatibleText(RECT rect, HDC hdc, LPCWSTR text, int fontSize, COLORREF dwmDisabledTextColor, DWORD format, LONG fontWeight = FW_NORMAL, int glowSize=10, int xOffset=0, int yOffset=0);
	static void DrawDefaultText(RECT rect, HDC hdc, LPCWSTR text, int fontSize, COLORREF textColor, DWORD format, LONG fontWeight = FW_NORMAL, int xOffset = 0, int yOffset = 0);
	static bool EndsWith(LPCTSTR string, LPCTSTR end);
	static set<tstring, TStringSortTemplate> GetDirectoryEntries(LPCTSTR lpFileName, int ft, tstring specialDirExt=TEXT(""));
	static tstring GetKnownFolderPath(const KNOWNFOLDERID &rfid);
	static set<tstring, TStringSortTemplate> SplitTString(tstring str, tstring separator, bool ignoreEmptyStrings=false);
	static bool MoveWindowIntoVisibleArea(HWND hWnd);
	static POINT CenterScreen(SIZE windowSize, bool workingArea = true, bool primaryScreen = false);
	static POINT CenterScreen(LONG cx, LONG cy, bool workingArea = true, bool primaryScreen = false);
	static bool LockDrive(TCHAR cDrive, bool bLock);
	static Grid CalculateGridArea(int count);
	static void CreateRoundRectPath(GraphicsPath* path, RECT rect, int radius, int offset = 0);
	static void CreateRoundRectPath(GraphicsPath* path, RECT rect, int radiusTopLeft, int radiusTopRight, int radiusBottomRight, int radiusBottomLeft, int offset = 0);
	static void CreateRoundRectPath(GraphicsPath* path, RECT rect, int radiusTopLeft, int radiusTopRight, int radiusBottomRight, int radiusBottomLeft, int offsetLeft, int offsetTop, int offsetRight, int offsetBottom);
	static void DrawPNGFromResource(HINSTANCE hInstance, HDC hdc, LPCTSTR resourceName, int x, int y, int width, int height);
	static HICON GetSmallWindowIcon(HWND hWnd);
	static bool IsSpecialCassiopeiaWindow(HWND hWnd);
	static HWND GetLastValidTopLevelWindow();
	static tstring GetWindowFileName(HWND hWnd);
	static DWORD GetVolumeSerial(TCHAR volumeLetter);
	static tstring GetVolumeName(TCHAR volumeLetter);
	static TCHAR GetVolumeLetter(DWORD mask);
	static set<TCHAR> GetDrives(int driveType = -1);
	static bool ExistsFile(tstring fileName);
	static int GetEncoderClsid(tstring format, CLSID* pClsid);
	static bool IsWindowHanging(HWND hWnd);
	static tstring ConvertToString(int value);

private:
	static HWND HProgMan;
	static HWND HSHELLDLL_DefViewParent;
	static HWND HSHELLDLL_DefView;
	static HWND HSysListView32;

	static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
};

#endif